<html>
<head><meta charset="utf-8"><title>Why Needs is propagated to a receiver in check_method_call? · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20Needs.20is.20propagated.20to.20a.20receiver.20in.20check_method_call.3F.html">Why Needs is propagated to a receiver in check_method_call?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="187009539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20Needs%20is%20propagated%20to%20a%20receiver%20in%20check_method_call%3F/near/187009539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vlad <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20Needs.20is.20propagated.20to.20a.20receiver.20in.20check_method_call.3F.html#187009539">(Jan 30 2020 at 17:26)</a>:</h4>
<p>If method call is in <code>Needs::MutPlace</code> context (e.g. <code>*(foo.bar()) = 1;</code>), Needs::MutPlace is propagated to receiver expression <code>foo</code> (see <code>check_method_call</code>).<br>
But then, if autoref to <code>&amp;mut</code> occurs, such <code>Needs</code> (effectively) reconsidered in <code>convert_place_derefs_to_mutable</code>. So why <code>Needs</code> is propagated to a receiver in <code>check_method_call</code>? It looks like it just shouldn't. </p>
<p>I made an example when such propagation leads to using <code>index_mut</code> when it does not need and to false-positive E0596.</p>
<p>Setup:</p>
<div class="codehilite"><pre><span></span>struct S;
impl S {
    // Note `&amp;self`, not `&amp;mut self`!
    fn foo(&amp;self) -&gt; &amp;&#39;static mut i32 {
        Box::leak(Box::new(1))
    }
}

struct Indexable;

impl std::ops::Index&lt;u8&gt; for Indexable {
    type Output = S;

    fn index(&amp;self, index: u8) -&gt; &amp;Self::Output {
        println!(&quot;non mut&quot;);
        Box::leak(Box::new(S))
    }
}
impl std::ops::IndexMut&lt;u8&gt; for Indexable {
    fn index_mut(&amp;mut self, index: u8) -&gt; &amp;mut Self::Output {
        println!(&quot;mut&quot;);
        Box::leak(Box::new(S))
    }
}
</pre></div>


<p>This code uses <code>index_mut</code> (why?)</p>
<div class="codehilite"><pre><span></span>fn main() {
    let a = &amp;mut Indexable;
    *(a[0].foo()) = 1;
}
</pre></div>


<p>This code produces <code>E0596</code> (but looks it shouldn't)</p>
<div class="codehilite"><pre><span></span>fn main() {
    let a = &amp;Indexable;
    *(a[0].foo()) = 1;
}
</pre></div>


<p>This can be compiled if write</p>
<div class="codehilite"><pre><span></span>fn main() {
    let a = &amp;Indexable;
    *((&amp;a[0]).foo()) = 1;
}
</pre></div>



<a name="188361795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20Needs%20is%20propagated%20to%20a%20receiver%20in%20check_method_call%3F/near/188361795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vlad <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20Needs.20is.20propagated.20to.20a.20receiver.20in.20check_method_call.3F.html#188361795">(Feb 17 2020 at 09:03)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>